/*
 * Copyright (c) 2016 zhangcm. All Rights Reserved.
 */
package com.jnzc.ocr.tool.zuul.filter;

import com.google.common.collect.Lists;
import com.google.common.collect.Maps;
import com.jnzc.ocr.common.utils.InputStreamUtils;
import com.jnzc.ocr.common.utils.JsonUtils;
import com.netflix.zuul.ZuulFilter;
import com.netflix.zuul.context.RequestContext;
import org.apache.commons.lang3.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.stereotype.Component;

import javax.servlet.ServletInputStream;
import javax.servlet.http.HttpServletRequest;
import java.io.IOException;
import java.io.InputStream;
import java.util.List;
import java.util.Map;

/**
 * @author zhangcm
 * @version 1.0, 2017/8/30
 */
@Component
public class RequestInfoFilter extends ZuulFilter {

    private final Logger logger = LoggerFactory.getLogger(RequestInfoFilter.class);

    private static final List<String> CONTENT_TYPE_LIST = Lists.newArrayList("application/x-www-form-urlencoded", "application/json");

    public String filterType() {
        return "pre";
    }

    public int filterOrder() {
        return 1;
    }

    public boolean shouldFilter() {
        return true;
    }

    public Object run() {
        RequestContext context = RequestContext.getCurrentContext();
        HttpServletRequest request = context.getRequest();
        Map<String, Object> infoMap = Maps.newLinkedHashMap();
        infoMap.put("method", request.getMethod());
        infoMap.put("url", request.getRequestURL());
        infoMap.put("contentType", request.getContentType());
        switch (request.getMethod()) {
            case "POST": fillPostInfo(infoMap, request); break;
        }
        logger.info("[request] {}", JsonUtils.toJson(infoMap));
        return null;
    }

    private void fillPostInfo(Map<String, Object> infoMap, HttpServletRequest request) {
        String contentType = this.getContentType(request);
        if(!CONTENT_TYPE_LIST.contains(contentType)) {
            return;
        }
        try {
            ServletInputStream is = request.getInputStream();
            String body = InputStreamUtils.toString(is, request.getCharacterEncoding());
            infoMap.put("body", body);
        } catch (IOException e) {
            e.printStackTrace();
        }
    }

    private String getContentType(HttpServletRequest request) {
        String contentType = request.getContentType();
        if(StringUtils.isEmpty(contentType)) {
            return null;
        }
        contentType = StringUtils.split(contentType, ";")[0];
        return contentType.toLowerCase();
    }
}
